#ifndef _EMB_STDLIB_QUEUE_H_
#define _EMB_STDLIB_QUEUE_H_

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>

#include "EmbStdLib_Type.h"

#define QUEUE_SUCCESS (0)
#define QUEUE_ERROR_FULL (1)
#define QUEUE_ERROR_EMPTY (2)
#define QUEUE_ERROR_MEMORY (3)
#define QUEUE_ERROR_SIZE (4)

// Define global static arrays to store messages for each queue
#define MAX_QUEUE1_MESSAGES 4
#define MAX_QUEUE1_MESSAGE_LENGTH 8
#define MAX_QUEUE2_MESSAGES 6
#define MAX_QUEUE2_MESSAGE_LENGTH 16

// Log level enumeration
typedef enum
{
  LOG_LEVEL_DEBUG,
  LOG_LEVEL_INFO,
  LOG_LEVEL_WARN,
  LOG_LEVEL_ERROR
} LogLevel;

typedef struct
{
  uint8 *data;           // Dynamically allocated message queue
  uint32 max_messages;   // Maximum number of messages in the queue
  uint32 message_length; // Length of each message
  uint32 current_memory; // Current memory usage of the queue
  uint32 front;          // Front of the queue
  uint32 rear;           // Rear of the queue
  uint32 size;           // Current size of the queue
  boolean log_enabled;   // Whether logging is enabled
  LogLevel log_level;    // Current log level
  uint32 log_error;      // Log error status
} Queue;

uint8 QueueInit(boolean log_enabled, LogLevel log_level, Queue *queue, uint32 max_messages, uint32 message_length, uint8 *data);
void destroyQueue(Queue *queue);
uint32 putQueue(Queue *queue, const uint8 *message, uint32 message_length);
uint32 getQueue(Queue *queue, uint8 *message, uint32 message_length);
void printQueue(Queue *queue);

#endif // _EMB_STDLIB_QUEUE_H_
